home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / PCCardNetworkSample / EnablerSmpl.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  13.0 KB  |  456 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        EnablerSmpl.c
  3.  
  4.     Contains:    This is a sample enabler for an ethernet PC Card, which demonstrates how to
  5.                 create a port module
  6.                 registration item and set a custom module name that will be used to
  7.                 identify the device driver. 
  8.  
  9.     Written by: Carl Fallis - writer of the original sample on which this sample is based
  10.                 Hiroko Nishimura - modified the sample to support the Ratoc REX-5589 Ethernet 
  11.                     PC Card.
  12.                 Rich Kubota - modified to demonstrate handling of custom port registration    
  13.  
  14.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  15.  
  16.                 You may incorporate this Apple sample source code into your program(s) without
  17.                 restriction. This Apple sample source code has been provided "AS IS" and the
  18.                 responsibility for its operation is yours. You are not permitted to redistribute
  19.                 this Apple sample source code as "Apple sample source code" after having made
  20.                 changes. If you're going to re-distribute the source, we require that you make
  21.                 it clear in the source that the code was descended from Apple sample source
  22.                 code, but that you've made changes.
  23.  
  24.     Change History (most recent first):
  25.                 8/16/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  26.                 
  27.  
  28. */
  29.  
  30. #include <Types.h>
  31. #include <Errors.h>
  32. #include <Devices.h>
  33. #include <Gestalt.h>
  34. #include <CodeFragments.h>
  35. //#include <DriverServices.h>
  36. #include <PCCardEnablerPlugin.h>
  37. #include <PCCardTuples.h>
  38. #include <OpenTptModule.h>
  39. #include <OpenTptPCISupport.h>
  40. #include <OpenTptDevLinks.h>
  41. #include "EnablerSample.h"
  42. #include "MyPortCalls.h"
  43.  
  44. // use the TupleDumper PPC utility which comes with the PC Card DDK to display the data
  45. // associated with the following Tuples.  The following are used with the _IdentifyCard call
  46. // to verify that the proper card is being supported.
  47.  
  48. const unsigned char kCISTPL_VERS_1_Data[] = "\4\1PCMCIA LAN MBH10304  ES\0  01\0\xff";
  49.  
  50. const unsigned char kCISTPL_CONFIG_Data[] = {0x05,0x20,0xF0,0x03,0x03,0x00,0xFF};
  51.  
  52. const unsigned char kCISTPL_CFTABLE_ENTRY_Data[] = {0xE0,0xC1,0x99,0x5F,0x55,0xC5,0x4B,0xD5,
  53.                                         0x19,0x86,0x10,0x26,0x45,0x65,0x30,0xFF,
  54.                                         0xFF,0x20,0xFF};
  55.  
  56. //----------------------------------------------------------------------
  57. //    Local Prototypes
  58.  
  59. typedef PCCardTupleIterator PCCardTupleIteratorPtr;
  60.  
  61. OSStatus MyValidateHardware(const RegEntryID * lpCardEntry);
  62. OSStatus MyHandleCardEvent(const RegEntryID *cardRef, PCCardEvent theEvent);
  63. OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device, PCCardTupleIteratorPtr lpTupleIterator,
  64.             Byte desiredTuple, void *lptupleData, UInt32 *lpTupleBufferSize, Byte *lpFoundTuple);
  65. OSStatus MyGetNextTuple(PCCardTupleIteratorPtr tupleIterator, Byte desiredTuple, void *tupleData, ByteCount *tupleBufferSize, Byte *foundTuple);
  66.  
  67.  
  68. OSStatus _IdentifyCard(const RegEntryID *    lpCardEntry);
  69. Boolean  CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName);
  70. OSStatus CreatePortProperties(const RegEntryID *cardRef);
  71. OSStatus MyAddDeviceProperties(const RegEntryID *cardRef, UInt32 device);
  72. OSStatus MyFinalizeDevice(UInt32 socket, UInt32 device, const RegEntryID *deviceRef);
  73. void    CallPortScanner(void);
  74. void    EnablerOfflinePort(const RegEntryID *cardRef);
  75. //----------------------------------------------------------------------
  76. // Globals
  77.  
  78.  
  79. #pragma export on 
  80.  
  81. // --------------------
  82. // Here's the exported Driver Descriptor
  83. DriverDescription TheDriverDescription = {
  84.     /*
  85.      * Signature info
  86.      */
  87.     kTheDescriptionSignature,                /* OSType driverDescSignature            */
  88.     kInitialDriverDescriptor,                /* DriverDescVersion driverDescVersion    */
  89.     /*
  90.      * DriverType driverType - these are defined in
  91.      */
  92.     kPluginNamePString,                        /* Name of hardware */
  93.     kVersionMajor, kVersionMinor,            /* NumVersion version */
  94.     kVersionStage, kVersionNonRel,
  95.  
  96.     /*
  97.      * DriverOSRuntime driverOSRuntimeInfo
  98.      */
  99.     kDriverIsLoadedUponDiscovery    |    /* Loader runtime options                */
  100.     kDriverIsUnderExpertControl,        /* I/O expert handles loads/opens        */
  101.     kPluginNamePString,                    /* Str31 driverName    (OpenDriver param)    */
  102.     0, 0, 0, 0, 0, 0, 0, 0,                /* UInt32 driverDescReserved[8]            */
  103.  
  104.     /*
  105.      * DriverOSService Information. This section contains a vector count followed by
  106.      * a vector of structures, each defining a driver service.
  107.      */
  108.     1,                                        /*     ServiceCount nServices                */
  109.  
  110.     /*
  111.      * DriverServiceInfo service[0]
  112.      */
  113.     kServiceCategoryPCCard,                    /* OSType serviceCategory                */
  114.     kServiceTypePCCardEnabler,                /* OSType serviceType                    */
  115.  
  116.     1, 0,developStage, 1
  117.     };
  118.  
  119.  
  120.  
  121. // --------------------
  122. // Here's the exported Plugin Function Table…
  123. PCCardEnablerPluginDispatchTable ThePluginDispatchTable =
  124. {
  125.     /* PCCardEnablerPluginHeader */
  126.     { kPCCardEnablerPluginCurrentVersion, 0, 0, 0 },
  127.  
  128.     /* CEValidateHardwareProc            */    MyValidateHardware,
  129.     /* CEInitializeProc                    */    CEInitializeCard,
  130.     /* CECleanupProc                    */    CEFinalizeCard,
  131.     /* CEPowerManagementProc            */    CEPowerManagement,
  132.  
  133.     /* CEHandleEventProc                */    CEHandleCardEvent,
  134.     /* CEGetCardInfoProc                */    CEGetCardInfo,
  135.     /* CEAddCardPropertiesProc            */    CEAddCardProperties,
  136.     /* CEGetDeviceCountProc                */    CEGetDeviceCount,
  137.  
  138.     /* CEGetDeviceNameProc                */    CEGetDeviceName,
  139.     /* CEGetDeviceCompatibleNameProc    */    CEGetDeviceCompatibleNames,
  140.     /* CEGetDeviceTypeProc                */    CEGetDeviceType,
  141.     /* CEGetDeviceTypeNameProc            */    CEGetDeviceTypeName,
  142.     /* CEAddDevicePropertiesProc        */    MyAddDeviceProperties,
  143.     /* CEConfigureDeviceProc            */    CEConfigureDevice,
  144.     /* CEFinalizeDeviceProc                */    MyFinalizeDevice,
  145.  
  146.     /* CEValidateCISProc                */    CEValidateCIS,
  147.     /* CEGetFirstTupleProc                */    MyGetFirstTuple,
  148.     /* CEGetNextTupleProc                */    MyGetNextTuple,
  149.  
  150.     /* InterruptHandler                    */    CEDefaultInterruptHandler,
  151.     /* InterruptEnabler                    */    NULL,
  152.     /* InterruptDisabler                */    NULL
  153. };
  154.  
  155.  
  156. //----------------------------------------------------------------------
  157. //    Determine whether the plugin can support this card. 
  158. //  Returning noErr means that the card is supported
  159. OSStatus MyValidateHardware(const RegEntryID *lpCardEntry)
  160. {
  161.     OSStatus             err;
  162.     
  163. #if    DEBUG    
  164.     DebugStr("\pCustomCardEnabler:  MyValidateHardware");
  165. #endif
  166.     if (!(lpCardEntry)) return(paramErr);
  167.  
  168.     // see if we are supposed to handle this card, set global card id
  169.     err = _IdentifyCard(lpCardEntry);
  170.  
  171. #if    DEBUG1    
  172.     if (err == noErr) DebugStr("\p Enabler will handle this card!;g");
  173. #endif
  174.     return(err);
  175. }
  176.  
  177.  
  178. //----------------------------------------------------------------------
  179. //    Look to see if this is a card we are supposed to handle
  180. //    If it is return noErr, other wise return kUnsupportedCardErr
  181. // 
  182. // Identification of the IBM OEM Ethernet card 
  183. //    1) check the manufacturer's ID
  184. //    2) check the vers 1 for IBM Corp Ethernet
  185. //    3) check for the config table entry for the bad entry so that we are sure that 
  186. //       this is the correct card we say it is our card
  187. OSStatus _IdentifyCard(const RegEntryID *lpCardEntry)
  188. {
  189.     PCCardTupleIteratorPtr     iter;
  190.     OSStatus                err = noErr;
  191.     UInt32                    size=MAX_TUPLE_SIZE, socket, device;
  192.     Boolean                    match = false; 
  193.     int                        i=0;
  194.     
  195.     
  196. #if    DEBUG    
  197.     DebugStr("\pCustomCardEnabler:  _IdentifyCard");
  198. #endif
  199.  
  200.     if(!(lpCardEntry)  ) return(paramErr);
  201.  
  202.     err =  CEGetSocketAndDeviceFromRegEntry(lpCardEntry, &socket, &device);
  203.     if (err != noErr)
  204.         return(err);                            
  205.  
  206.     iter = PCCardNewTupleIterator();
  207.     if (iter == NULL)
  208.         return memFullErr;
  209.  
  210.     err = CECompareCISTPL_MANFID(lpCardEntry, 
  211.                                     kManifID,
  212.                                     kManifInfo,
  213.                                     &match); 
  214.         
  215.     if ((err == noErr) && (match == true))
  216.     {
  217.         // do other checking if required like calling CSGetFirstTuple
  218.         // to get more tuple info to compare against
  219.     }
  220.     else
  221.         err = kUnsupportedCardErr;
  222.         
  223.         // dispose of the tuple iterator    
  224.     PCCardDisposeTupleIterator(iter);
  225.     
  226.     return(err);
  227. }
  228.  
  229. //----------------------------------------------------------------------
  230. //     Look for the kPCCardInsertionMessage as the event
  231. OSStatus MyHandleCardEvent(const RegEntryID *cardRef, PCCardEvent theEvent)
  232. {
  233.     OSStatus    err = noErr;
  234.     
  235. #if    DEBUG    
  236.  
  237.     DebugStr("\pMyHandleCardEvent called");
  238. #endif
  239.  
  240.     switch (theEvent)
  241.     {
  242.         case kPCCardInsertionMessage:
  243. #if    DEBUG1    
  244.             DebugStr("\pkPCCardInsertionMessage event passed to MyHandleCardEvent;g");
  245. #endif
  246.             break;
  247.     
  248.         case kPCCardEjectionRequestMessage:
  249.         case kPCCardRemovalMessage:
  250. #if    DEBUG    
  251.             DebugStr("\p kPCCardRemovalMessage called");
  252. #endif
  253. //            EnablerOfflinePort(cardRef);
  254.             break;
  255.     }
  256.             
  257.     if (err == noErr)
  258.             // call the default HandleEventProc to complete processing of the event.
  259.         err = CEHandleCardEvent(cardRef, theEvent);
  260.     
  261.     return err;
  262. }
  263.  
  264.  
  265. //----------------------------------------------------------------------
  266. OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device,            
  267.                                 PCCardTupleIteratorPtr lpTupleIterator,
  268.                                 Byte desiredTuple,             
  269.                                 void *lpTupleData,
  270.                                 UInt32 *lpTupleBufferSize,
  271.                                 Byte *lpFoundTuple)
  272. {
  273.     OSStatus                 err = noErr;
  274.     unsigned char            *dataPtr = (unsigned char *)lpTupleData;
  275.     UInt32                    i=0;
  276.  
  277.  
  278. #if    DEBUG    
  279. //    DebugStr("\pCustomCardEnabler:  MyGetFirstTuple");        
  280. #endif
  281.     if(!(lpTupleIterator && lpFoundTuple && lpTupleData && *lpTupleBufferSize))
  282.         return(paramErr);
  283.     
  284.     
  285.     
  286.     err = CSGetFirstTuple(socket, device,lpTupleIterator,desiredTuple,
  287.                                 lpTupleData,lpTupleBufferSize,lpFoundTuple);
  288.     if (err != noErr)
  289.         return(err);                            
  290.  
  291.     if (*lpTupleBufferSize == 0)
  292.         return(err);
  293.         
  294.     if (*lpFoundTuple == CISTPL_VERS_1)
  295.     {
  296. #if    DEBUG1
  297. //        DebugStr("\pCISTPL_VERS_1");
  298. #endif
  299.         for( i = 0; i < sizeof(kCISTPL_VERS_1_Data); i++)
  300.             dataPtr[i] = kCISTPL_VERS_1_Data[i];
  301.                 
  302.         *lpTupleBufferSize = sizeof(kCISTPL_VERS_1_Data);
  303.         
  304.     }
  305.             
  306.     if (*lpFoundTuple == CISTPL_CONFIG)
  307.     {
  308. #if    DEBUG1
  309.         DebugStr("\pCISTPL_CONFIG");
  310. #endif
  311.         for( i = 0; i < sizeof(kCISTPL_CONFIG_Data); i++)
  312.             dataPtr[i] = kCISTPL_CONFIG_Data[i];    
  313.         *lpTupleBufferSize = sizeof(kCISTPL_CONFIG_Data);
  314.     }
  315.     if (*lpFoundTuple == CISTPL_CFTABLE_ENTRY)
  316.     {
  317. #if    DEBUG1
  318.         DebugStr("\pCISTPL_CFTABLE_ENTRY");
  319. #endif
  320.         for( i = 0; i < sizeof(kCISTPL_CFTABLE_ENTRY_Data); i++)
  321.             dataPtr[i] = kCISTPL_CFTABLE_ENTRY_Data[i];    
  322.         *lpTupleBufferSize = sizeof(kCISTPL_CFTABLE_ENTRY_Data);
  323.     }
  324.  
  325.     return(err);
  326. }            
  327.  
  328. //
  329. // MyGetNextTuple 
  330. //            
  331. OSStatus MyGetNextTuple(PCCardTupleIteratorPtr lpTupleIterator, 
  332.                         Byte desiredTuple, 
  333.                         void *lpTupleData, 
  334.                         ByteCount *lpTupleBufferSize, 
  335.                         Byte *lpFoundTuple)
  336. {
  337.     OSStatus                 err = noErr;
  338.     unsigned char            *dataPtr = (unsigned char *)lpTupleData;
  339.     UInt32                    i=0;
  340.     
  341.     
  342. #if    DEBUG    
  343. //    DebugStr("\pCustomCardEnabler:  MyGetNextTuple");        
  344. #endif
  345.     if(!(lpTupleIterator && lpFoundTuple && lpTupleData && *lpTupleBufferSize))
  346.         return(paramErr);
  347.     
  348.     
  349.     
  350.     err = CSGetNextTuple(lpTupleIterator, desiredTuple,lpTupleData,lpTupleBufferSize,
  351.                                 lpFoundTuple);
  352.     if (err != noErr)
  353.         return(err);                            
  354.     
  355.     
  356.     if (*lpTupleBufferSize == 0)
  357.         return(err);
  358.         
  359.     if (*lpFoundTuple == CISTPL_VERS_1)
  360.     {
  361. #if    DEBUG1
  362. //        DebugStr("\pCISTPL_VERS_1");
  363. #endif
  364.         for( i = 0; i < sizeof(kCISTPL_VERS_1_Data); i++)
  365.             dataPtr[i] = kCISTPL_VERS_1_Data[i];    
  366.         *lpTupleBufferSize = sizeof(kCISTPL_VERS_1_Data);
  367.     }        
  368.     if (*lpFoundTuple == CISTPL_CONFIG)
  369.     {
  370. #if    DEBUG1
  371.         DebugStr("\pCISTPL_CONFIG");
  372. #endif
  373.         for( i = 0; i < sizeof(kCISTPL_CONFIG_Data); i++)
  374.             dataPtr[i] = kCISTPL_CONFIG_Data[i];    
  375.         *lpTupleBufferSize = sizeof(kCISTPL_CONFIG_Data);
  376.     }
  377.     
  378.     if (*lpFoundTuple == CISTPL_CFTABLE_ENTRY)
  379.     {
  380. #if    DEBUG1
  381.         DebugStr("\pCISTPL_CFTABLE_ENTRY");
  382. #endif
  383.         for( i = 0; i < sizeof(kCISTPL_CFTABLE_ENTRY_Data); i++)
  384.             dataPtr[i] = kCISTPL_CFTABLE_ENTRY_Data[i];    
  385.         *lpTupleBufferSize = sizeof(kCISTPL_CFTABLE_ENTRY_Data);
  386.     }
  387.  
  388.     return(err);
  389. }                        
  390.  
  391.  
  392. //----------------------------------------------------------------------
  393. //     Pass in a VERS1 tuple and check that the manufacturer name and card name are
  394. // the the same as the ones passed in
  395. Boolean CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName)
  396. {
  397.     unsigned char          *ptr;
  398.     
  399.     
  400. #if    DEBUG    
  401. //    DebugStr("\pCustomCardEnabler:  CheckVers1Tuple");
  402. #endif
  403.     // the manufacturer name is a null terminated string starting in byte three
  404.     ptr = &(data[2]);
  405.     if(CStrCmp((const char *) ptr, manufacturerName) == 0)
  406.     { 
  407.         // the card name is a null terminated string that starts after the manufacturer name
  408.         while(*ptr++)
  409.             ;
  410.         if(CStrCmp((const char *) ptr, cardName) != 0)
  411.             return(false);
  412.     }
  413.     else
  414.         return(false);                            
  415.     
  416.     // if we make it to here, both names match
  417.     return(true);
  418. }
  419.  
  420.  
  421. OSStatus MyFinalizeDevice(UInt32 socket, UInt32 device, const RegEntryID *deviceRef)
  422. {
  423.     OSStatus    err;
  424. #if    DEBUG    
  425.     DebugStr("\p MyFinalizeDevice called");
  426. #endif
  427.     EnablerOfflinePort(deviceRef);
  428.     err = CEFinalizeDevice(socket, device, deviceRef);
  429.     return err;
  430. }
  431.  
  432. OSStatus MyAddDeviceProperties(const RegEntryID *cardRef, UInt32 device)
  433. {
  434. #pragma unused ( device )
  435.     OSStatus     err;
  436.  
  437. #if    DEBUG    
  438.     DebugStr("\pCustomCardEnabler:  MyAddDeviceProperties");        
  439. #endif
  440.     
  441.     //    This would be a great place to register a port, however, this creates a problem for 
  442.     //  the shared library since this code could be called at start up time prior to
  443.     //  the availability of Open Transport.  While I could weak link with OT, if the library
  444.     // is not present, then even when the library becomes available, CFM will not relink
  445.     //  with the OT libraries.  To handle this case, we implement a port scanner.
  446.     
  447.     err = CreatePortProperties(cardRef);
  448.         CallPortScanner();
  449.     
  450.     return err;
  451. }
  452.  
  453.  
  454.  
  455.  
  456.